package fr.cdj.thebox.client.content;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import net.customware.gwt.presenter.client.EventBus;
import net.customware.gwt.presenter.client.widget.WidgetPresenter;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.inject.Inject;

import fr.cdj.thebox.client.content.ui.ContentDisplay;
import fr.cdj.thebox.client.events.DeleteFilesSuccessEvent;
import fr.cdj.thebox.client.events.DeleteFilesSuccessHandler;
import fr.cdj.thebox.client.events.DownloadFilesRequestEvent;
import fr.cdj.thebox.client.events.DownloadFilesRequestHandler;
import fr.cdj.thebox.client.events.ListFilesRequestEvent;
import fr.cdj.thebox.client.events.ListFilesSuccessEvent;
import fr.cdj.thebox.client.events.ListFilesSuccessHandler;
import fr.cdj.thebox.client.events.SearchFilesRequestEvent;
import fr.cdj.thebox.client.events.SearchFilesRequestHandler;
import fr.cdj.thebox.client.events.SortFilesRequestEvent;
import fr.cdj.thebox.client.events.SortFilesRequestHandler;
import fr.cdj.thebox.shared.FileMetaData;

public class ContentPresenter extends WidgetPresenter<ContentDisplay> {

	@Inject
	private FileItemPresenter.Factory fileItemPresenterFactory;

	private List<FileItemPresenter> fileItemPresenters;

	@Inject
	public ContentPresenter(ContentDisplay display, EventBus eventBus) {
		super(display, eventBus);
		fileItemPresenters = new ArrayList<FileItemPresenter>();
	}

	@Override
	protected void onBind() {
		registerHandler(eventBus.addHandler(ListFilesSuccessEvent.getType(), new ListFilesSuccessHandler() {
			@Override
			public void onListFilesSuccess(final ListFilesSuccessEvent event) {
				if (event.getEventSource() == ContentPresenter.this && event.getFileList() != null) {
					fileItemPresenters.clear();
					display.clearItems();
					for (FileMetaData fileMetaData : event.getFileList().getFilesMetaDatas()) {
						FileItemPresenter fileItemPresenter = fileItemPresenterFactory.create(fileMetaData);
						fileItemPresenter.setFileItemPresenterFactory(fileItemPresenterFactory);
						fileItemPresenter.bind();
						fileItemPresenter.revealDisplay();
						fileItemPresenters.add(fileItemPresenter);
					}
					refreshDisplay();
				}
			}
		}));
		registerHandler(eventBus.addHandler(DownloadFilesRequestEvent.getType(), new DownloadFilesRequestHandler() {
			@Override
			public void onDownloadFilesRequest(final DownloadFilesRequestEvent event) {
				List<String> paths = getSelectedPaths();
				if (!paths.isEmpty()) {
					String url = GWT.getModuleBaseURL() + "file";
					FormPanel form = new FormPanel("_self");
					Hidden hid = new Hidden();
					hid.setName("paths");
					StringBuilder pathsStringBuilder = new StringBuilder();
					for (String path : paths) {
						pathsStringBuilder.append(path).append(";");
					}
					hid.setValue(pathsStringBuilder.substring(0, pathsStringBuilder.length() - 1));
					form.add(hid);
					form.setAction(url);
					form.setMethod(FormPanel.METHOD_POST);
					RootPanel.get().add(form);
					form.submit();
					RootPanel.get().remove(form);
				}
			}
		}));
		registerHandler(eventBus.addHandler(DeleteFilesSuccessEvent.getType(), new DeleteFilesSuccessHandler() {
			@Override
			public void onDeleteFilesSuccess(DeleteFilesSuccessEvent event) {
				eventBus.fireEvent(new ListFilesRequestEvent(ContentPresenter.this, ""));
			}
		}));
		registerHandler(eventBus.addHandler(SortFilesRequestEvent.getType(), new SortFilesRequestHandler() {
			@Override
			public void onSortFilesRequest(SortFilesRequestEvent event) {
				refreshDisplay();
			}
		}));
		registerHandler(eventBus.addHandler(SearchFilesRequestEvent.getType(), new SearchFilesRequestHandler() {
			@Override
			public void onSearchFilesRequest(SearchFilesRequestEvent event) {
				spreadSearch(event.getSearch());
			}
		}));
	}

	private void spreadSearch(String search) {
		for (FileItemPresenter presenter : fileItemPresenters) {
			presenter.spreadSearch(search);
		}
	}

	private void refreshDisplay() {
		Collections.sort(fileItemPresenters);
		display.clearItems();
		for (FileItemPresenter presenter : fileItemPresenters) {
			display.addFileItem(presenter.getDisplay());
		}
	}

	@Override
	protected void onUnbind() {
	}

	@Override
	protected void onRevealDisplay() {
	}

	public List<String> getSelectedPaths() {
		List<String> paths = new ArrayList<String>();
		for (FileItemPresenter fileItemPresenter : fileItemPresenters) {
			for (FileMetaData fileMetaData : fileItemPresenter.getMetaDatasSelected()) {
				paths.add(fileMetaData.getPath());
			}
		}
		return paths;
	}

}
